package org.budo.dubbo.protocol.http.dispatcher.websocket;

import javax.servlet.ServletContext;
import javax.websocket.server.ServerContainer;
import javax.websocket.server.ServerEndpointConfig;

import org.budo.support.lang.util.ReflectUtil;
import org.budo.support.spring.context.aware.RootApplicationContextRefreshedEventListener;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.web.context.ServletContextAware;

import lombok.Getter;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;

/**
 * @author lmw
 */
@Slf4j
@Getter
@Setter
public class BudoHttpWebSocketServerContainerInitializer extends RootApplicationContextRefreshedEventListener implements ServletContextAware {
    private String path = "/ws";

    private Class<?> endpointClass;

    private ServletContext _servletContext;

    public BudoHttpWebSocketServerContainerInitializer() {
        if (ReflectUtil.hasClass("javax.websocket.MessageHandler")) {
            this.endpointClass = BudoHttpWebSocketServerEndpoint.class;
            log.info("#32 endpointClass is  BudoHttpWebSocketServerEndpoint");
        } else {
            log.warn("#33 endpointClass is null, no javax.websocket");
        }
    }

    @Override
    protected void onRootApplicationContextRefreshedEvent(ContextRefreshedEvent contextRefreshedEvent) {
        ServerContainer serverContainer = (ServerContainer) this._servletContext.getAttribute("javax.websocket.server.ServerContainer");

        if (null == serverContainer) {
            log.error("#24 onRootApplicationContextRefreshedEvent, serverContainer=" + serverContainer + ", servletContext=" + this._servletContext //
                    + ", contextRefreshedEvent=" + contextRefreshedEvent);
            return;
        }

        if (null == this.getEndpointClass()) {
            log.error("#48 endpointClass is null, this=" + this);
            return;
        }

        try {
            ServerEndpointConfig endpointConfig = ServerEndpointConfig.Builder.create(this.getEndpointClass(), this.getPath()).build();
            serverContainer.addEndpoint(endpointConfig);
        } catch (Throwable e) {
            log.error("#32 addEndpoint error, e=" + e, e);
        }

        log.warn("#35 onRootApplicationContextRefreshedEvent, after addEndpoint");
    }

    @Override
    public void setServletContext(ServletContext servletContext) {
        this._servletContext = servletContext;
    }
}